local nl = require'luaNumeric'
require 'luaFDTD3D'
local plot = require "Q2DViewerEx"

----------------------------------------------------------------------------------------------------------------------------------------
--初始化参数
local TimeDomainProbePostView={
	funs = {};
	xAxis = 0;
	ytype = 4;
	xtype = 1;
};
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--创建表和创建元表
function TimeDomainProbePostView:new (o)
	o = o or {};
	self.__index = self;
	setmetatable(o,self)
	o:init();
	return o;
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--创建表和创建元表
function TimeDomainProbePostView:init ()
	self.funs = {};
	self.funs.abs = function(input) return nl.abs(input); end;
	self.funs.phs = function(input) return nl.arg(input)*180/pi; end;
	self.funs.real = function(input) return nl.real(input); end;
	self.funs.imag = function(input) return nl.imag(input); end;
	self.funs.log = function(input) 
		local  d = nl.abs(input);		
		for k,v in pairs(d) do 
			if d[k] < 1e-200 then d[k] = 1e-200; end
		end
		d = 20* nl.log10(d)
		return d; 
	end;
	self.fun_names = {};
	self.fun_names[1] = 'log';
	self.fun_names[2] = 'abs';
	self.fun_names[3] = 'phs';
	self.fun_names[4] = 'real';
	self.fun_names[5] = 'imag';	
	self.ytype = 4;
end
----------------------------------------------------------------------------------------------------------------------------------------


----------------------------------------------------------------------------------------------------------------------------------------
--更新数据
function TimeDomainProbePostView:refresh_figs ()
	self.probe:update();
	self.results = self.probe:time_domain_results();
	self:plot()
end
----------------------------------------------------------------------------------------------------------------------------------------


----------------------------------------------------------------------------------------------------------------------------------------
--画图
function TimeDomainProbePostView:plot ()
	self.view:clearGraphs();
	print( '延迟:', Geometry.syn_time()/Geometry.ref_units_time() );
	local fun = self.funs[ self.fun_names[self.ytype] ];
	for k,v in pairs(self.results.data ) do
		--print(self.results.data[k])
		local x = self.results.time;
		assert( #x == #self.results.data[k], '数据长度不匹配,请检查Probe设置或者重新计算')
		print( 'Reference signal['..self.probe:name()..']' , k)
		--self.probe:signal();
		if k == 'Reference signal['..self.probe:signal():name()..']' then 
			x = x - Geometry.syn_time()
		end
		self.view:addGraph(x/Geometry.ref_units_time(),  fun( self.results.data[k] ), k );
	end

	self.view:rescaleAxes();
	self:set_axis();
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--画图
function TimeDomainProbePostView:rescale ()
	self:update_parameters_from_ui();
	self:plot();
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--获得y坐标
function TimeDomainProbePostView:get_yaxis_lable()
	local str = '';
	if self.ytype ==1 then
		str="E/H Fields [dB]";
	elseif self.ytype ==2 then
		str="E/H Fields [Mag.]";
	elseif self.ytype ==3 then
		str="Argument of E/H Fields [arc.]";
	elseif self.ytype ==4 then
		str="Real part of E/H Fields";
	elseif self.ytype ==5 then
		str="Imag part of E/H Fields";
	end
	return str;
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--坐标设置
function TimeDomainProbePostView:set_axis()
	
	self.view.xAxis:setProperty( {name="time ["..Geometry.ref_units_time_str()..']'} )

	
	if self.ytype ==1 then
		self.view.yAxis:setProperty( {name="E/H Fields [dB]"} )
	elseif self.ytype ==2 then
		self.view.yAxis:setProperty( {name="E/H Fields [Mag.]"} )
	elseif self.ytype ==3 then
		self.view.yAxis:setProperty( {name="Argument of E/H Fields [arc.]"} )
	elseif self.ytype ==4 then
		self.view.yAxis:setProperty( {name="Real part of E/H Fields"} )
	elseif self.ytype ==5 then
		self.view.yAxis:setProperty( {name="Imag part of E/H Fields"} )
	end
	 self.view:rescaleAxes();
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--导出
function TimeDomainProbePostView:export_data (path)
	print(path);
	self.probe:save_fields_time(path);
end
----------------------------------------------------------------------------------------------------------------------------------------


--===========================================================================--
--格式化数据
function TimeDomainProbePostView:get_data()
	local header = nl.new_svector();
	header:add('Index')
	header:add('Time('..Geometry.ref_units_time_str()..')')
	local fun = self.funs[ self.fun_names[self.ytype] ];
	
	local num=0;
	for k,v in pairs(self.results.data ) do
		num = num+1;
		header:add(k)
	end

	local x = self.results.time;
	local fun = self.funs[ self.fun_names[self.ytype] ];
	local data = nl.new_eigen_smatrix(#self.results.time,num+2)

	for ii=1,#self.results.time do 
		data[{ii,1}] = tostring( ii );
		data[{ii,2}] = tostring( x[ii]/Geometry.ref_units_time() );
		local num=3;
		for k,v in pairs(self.results.data ) do
			--assert( #x == #self.results.data[k], '数据长度不匹配,请检查Probe设置或者重新计算')
			data[{ii,num}] = tostring(  fun( v )[ii] );
			num = num+1;
		end
	end
	
	return data,header;
end
--===========================================================================--

--===========================================================================--
--查看数据
function TimeDomainProbePostView:view_data()
	local data,header = self:get_data()
	if data and header then
		self.dataView  = Gallop.DataPost:create_data_table_to_ui();
		self.dataView:set_data(data);
		self.dataView:set_header(header);
	end 
end
--===========================================================================--

return TimeDomainProbePostView;
